package com.yipei.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yipei.business.domain.*;
import com.yipei.business.mapper.MlTradeEntrustOrderMapper;
import com.yipei.business.service.*;
import com.yipei.business.vo.DeliveryOrderVo;
import com.yipei.business.vo.EntrustOrderVo;
import com.yipei.business.vo.MlKLineMasterVo;
import com.yipei.business.vo.TodayDaealVo;
import com.yipei.common.core.domain.AjaxResult;
import com.yipei.common.core.domain.entity.MlTradeAccount;
import com.yipei.common.core.redis.RedisCache;
import com.yipei.common.utils.DateUtils;
import com.yipei.common.utils.SecurityUtils;
import com.yipei.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;

/**
 * 委托订单Service业务层处理
 *
 * @author yipei
 * @date 2024-12-21
 */
@Service
public class MlTradeEntrustOrderServiceImpl extends ServiceImpl<MlTradeEntrustOrderMapper, MlTradeEntrustOrder> implements IMlTradeEntrustOrderService {
    @Autowired
    private MlTradeEntrustOrderMapper mlTradeEntrustOrderMapper;
    @Autowired
    private IMlTradeAccountService iMlTradeAccountService;
    @Autowired
    private IMlPositionShareService iMlPositionShareService;

    @Autowired
    private IMlSymbolsInfoService iMlSymbolsInfoService;

    @Autowired
    private IMlTradeDealOrderService iMlTradeDealOrderService;
    @Autowired
    private IMlHolidayService iMlHolidayService;
    @Autowired
    private IMlBtsPointService iMlBtsPointService;

    @Autowired
    private IMlTodayProfitService iMlTodayProfitService;
    @Autowired
    private IMlAssetFlowService iMlAssetFlowService;
    @Autowired
    private IMlKLineMasterService iMlKLineMasterService;
    @Autowired
    private MlTradeDealOrderServiceImpl mlTradeDealOrderServiceimpl;

    @Autowired
    private IMlTradeAccountFinancingService iMlTradeAccountFinancingService;

    @Autowired
    private IMlTradingGroupService iMlTradingGroupService;

    @Autowired
    private IMlKLineMasterService mlKLineMasterService;

    /**
     * 查询委托订单
     *
     * @param id 委托订单主键
     * @return 委托订单
     */
    @Override
    public MlTradeEntrustOrder selectMlTradeEntrustOrderById(Long id) {
        return mlTradeEntrustOrderMapper.selectMlTradeEntrustOrderById(id);
    }

    /**
     * 查询委托订单列表
     *
     * @param mlTradeEntrustOrder 委托订单
     * @return 委托订单
     */
    @Override
    public List<MlTradeEntrustOrder> selectMlTradeEntrustOrderList(MlTradeEntrustOrder mlTradeEntrustOrder) {
        return mlTradeEntrustOrderMapper.selectMlTradeEntrustOrderList(mlTradeEntrustOrder);
    }

    /**
     * 新增委托订单
     *
     * @param mlTradeEntrustOrder 委托订单
     * @return 结果
     */
    @Override
    public int insertMlTradeEntrustOrder(MlTradeEntrustOrder mlTradeEntrustOrder) {
        mlTradeEntrustOrder.setCreateTime(DateUtils.getNowDate());
        return mlTradeEntrustOrderMapper.insertMlTradeEntrustOrder(mlTradeEntrustOrder);
    }

    /**
     * 修改委托订单
     *
     * @param mlTradeEntrustOrder 委托订单
     * @return 结果
     */
    @Override
    public int updateMlTradeEntrustOrder(MlTradeEntrustOrder mlTradeEntrustOrder) {
        mlTradeEntrustOrder.setUpdateTime(DateUtils.getNowDate());
        return mlTradeEntrustOrderMapper.updateMlTradeEntrustOrder(mlTradeEntrustOrder);
    }

    /**
     * 批量删除委托订单
     *
     * @param ids 需要删除的委托订单主键
     * @return 结果
     */
    @Override
    public int deleteMlTradeEntrustOrderByIds(Long[] ids) {
        return mlTradeEntrustOrderMapper.deleteMlTradeEntrustOrderByIds(ids);
    }

    /**
     * 删除委托订单信息
     *
     * @param id 委托订单主键
     * @return 结果
     */
    @Override
    public int deleteMlTradeEntrustOrderById(Long id) {
        return mlTradeEntrustOrderMapper.deleteMlTradeEntrustOrderById(id);
    }

    @Override
    @Transactional
    public AjaxResult addEntrustOrder(EntrustOrderVo entrustOrderVo) throws Exception {
        LocalTime now = LocalTime.now();
        LocalTime startTime = LocalTime.of(9, 0);
        LocalTime endtime1 = LocalTime.of(11, 30);
        LocalTime startTime1 = LocalTime.of(13, 0);
        LocalTime endTime = LocalTime.of(15, 0);
//        if (now.isAfter(startTime)&&now.isBefore(endtime1) &&now.isAfter(startTime1)&&now.isBefore(endTime)) {
        MlTradeEntrustOrder mlTradeEntrustOrder = entrustOrderVo.getMlTradeEntrustOrder();
        MlKLineMasterVo mlKLineMasterVo = entrustOrderVo.getMlKLineMasterVo();
//        mlTradeEntrustOrder.setSecName(mlKLineMasterVo.getF14());
        MlTradeAccount mlTradeAccount1 = SecurityUtils.getLoginMember().getMlTradeAccount();
        LambdaQueryWrapper<MlTradeAccount> mlTradeAccountLambdaQueryWrapper = new LambdaQueryWrapper<>();
        mlTradeAccountLambdaQueryWrapper.eq(MlTradeAccount::getTdAcc, mlTradeAccount1.getTdAcc());
        MlTradeAccount mlTradeAccount = iMlTradeAccountService.getOne(mlTradeAccountLambdaQueryWrapper);
        if (mlTradeAccount.getFFive() == null) {
            throw new Exception("请先配配置是否免五");
        }
        if (mlTradeAccount.getBuyRate() == null || mlTradeAccount.getSellRate() == null) {
            throw new Exception("请先配配置手续费费率");
        }
        String wt = this.createrDH("WT");
        mlTradeEntrustOrder.setWtDh(wt);
        BigDecimal wtJg = mlTradeEntrustOrder.getWtJg();
        String tdAcc = mlTradeAccount.getTdAcc();
        BigDecimal cash = mlTradeAccount.getCash();
        mlTradeEntrustOrder.setTdAcc(tdAcc);
        int randomNumber = ThreadLocalRandom.current().nextInt(180, 360);
        mlTradeEntrustOrder.setChSjc((long) randomNumber);
        List<TodayDaealVo> todayDaeas = this.getTodayDaea(mlTradeEntrustOrder.getSymbol(), mlTradeEntrustOrder.getSecName());
        if (mlTradeEntrustOrder.getWtFx().compareTo(BigDecimal.valueOf(0)) == 0) {
            List<TodayDaealVo> resultList = buildToday(todayDaeas);
            for (TodayDaealVo todayDaealVo : resultList) {
                if (wtJg.compareTo(todayDaealVo.getPrice()) >= 0) {
                    mlTradeEntrustOrder.setCjSl(mlTradeEntrustOrder.getWtSl());
                    wtJg = this.getBigDecimal(mlTradeEntrustOrder, todayDaealVo);
                } else {
                    /**
                     *
                     * 执行创建委托单，加进定时任务，扫描委托单，走成交逻辑
                     *
                     */
                    if (wtJg.multiply(mlTradeEntrustOrder.getWtSl()).compareTo(cash) > 0 && wtJg.multiply(mlTradeEntrustOrder.getWtSl()).compareTo(mlTradeAccount.getDjCash()) > 0 && wtJg.multiply(mlTradeEntrustOrder.getWtSl()).compareTo(mlTradeAccount.getKqZj()) > 0) {
                        return AjaxResult.error("资金不足");
                    }
                    this.createmlTradeEntrustOrder(mlTradeEntrustOrder);
                    /**
                     * 创建委托单资金扣除
                     */
                    this.createmlTradeEntrustAddOrsubtract(mlTradeAccount, mlTradeEntrustOrder);
                    return AjaxResult.success("创建买入委托单成功", mlTradeAccount.getCash().setScale(2, RoundingMode.DOWN));
                }
            }
            if (StringUtils.isEmpty(mlKLineMasterVo.getUpper_limit())) {
                mlKLineMasterVo.setUpper_limit("0");
            }
            if (wtJg.compareTo(new BigDecimal(mlKLineMasterVo.getUpper_limit())) >= 0) {
                return AjaxResult.error("买入价格超出涨停价");
            }
            if (wtJg.multiply(mlTradeEntrustOrder.getCjSl()).compareTo(cash) > 0 && wtJg.multiply(mlTradeEntrustOrder.getCjSl()).compareTo(mlTradeAccount.getDjCash()) > 0 && wtJg.multiply(mlTradeEntrustOrder.getCjSl()).compareTo(mlTradeAccount.getKqZj()) > 0) {
                return AjaxResult.error("资金不足");
            }
            createMlpositionShare(mlTradeEntrustOrder, tdAcc);
            this.createDealOrder(mlTradeEntrustOrder, wtJg, cash, wtJg, mlTradeAccount);
            insertMlTradeEntrustOrder(mlTradeEntrustOrder);
            return AjaxResult.success("买入成功", mlTradeAccount.getCash().setScale(2, RoundingMode.DOWN));
        } else {
            /**
             * 校验创建时间
             */
//            this.checkDate(mlTradeEntrustOrder);
            List<TodayDaealVo> resultList = createStoday(todayDaeas);
            LocalDate date = LocalDateTime.now().toLocalDate();
            LambdaQueryWrapper<MlPositionShare> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(MlPositionShare::getTdAcc, tdAcc).eq(MlPositionShare::getSymbol, mlTradeEntrustOrder.getSymbol()).lt(MlPositionShare::getCreateTime, date).orderByAsc(MlPositionShare::getCreateTime);
            List<MlPositionShare> mlPositionShares = iMlPositionShareService.list(lambdaQueryWrapper);
            BigDecimal kycwTotal = mlPositionShares.stream().map(MlPositionShare::getKyCw).reduce(BigDecimal.ZERO, BigDecimal::add);
            if (mlTradeEntrustOrder.getWtSl().compareTo(kycwTotal) > 0) {
                return AjaxResult.error("今日可卖仓位不足");
            }
            for (TodayDaealVo todayDaealVo : resultList) {
                if (wtJg.compareTo(todayDaealVo.getPrice()) <= 0) {
                    wtJg = getBigDecimal(mlTradeEntrustOrder, todayDaealVo);
                } else {
                    this.mlPositionShareSdCw(mlTradeEntrustOrder, mlPositionShares);
                    this.createmlTradeEntrustOrder(mlTradeEntrustOrder);
                    return AjaxResult.success("创建卖出委托单成功");
                }
            }
            if (StringUtils.isEmpty(mlKLineMasterVo.getLower_limit())) {
                mlKLineMasterVo.setUpper_limit("0");
            }
            if (wtJg.compareTo(new BigDecimal(mlKLineMasterVo.getLower_limit())) <= 0) {
                return AjaxResult.error("卖出价格低于跌停价价");
            }
            mlTradeDealOrderServiceimpl.createDealOrder(mlTradeEntrustOrder, mlTradeEntrustOrder.getWtJg(), String.valueOf(mlTradeEntrustOrder.getWtSl()), System.currentTimeMillis(), mlPositionShares, "1");
            mlTradeEntrustOrder.setWtZt(new BigDecimal(3));
            return AjaxResult.success(insertMlTradeEntrustOrder(mlTradeEntrustOrder));
        }
        //        }
//        else {
//            throw new Exception("不在交易时间范围内");
//        }
    }

    public List<TodayDaealVo> createStoday(List<TodayDaealVo> todayDaeas) {
        Optional<TodayDaealVo> min = todayDaeas.stream().filter(d -> "S".equals(d.getBsFlag())).min(Comparator.comparingLong(d -> {
            try {
                LocalTime tickTime = LocalTime.parse(d.getFormatTime()); // 或 d.getTime()
                return Math.abs(Duration.between(LocalTime.now(), tickTime).toMillis());
            } catch (Exception e) {
                return Long.MAX_VALUE; // 时间格式错误的跳过
            }
        }));
        List<TodayDaealVo> resultList = min.map(Collections::singletonList).orElse(Collections.emptyList());
        return resultList;
    }

    @Override
    public void mlPositionShareSdCw(MlTradeEntrustOrder mlTradeEntrustOrder, List<MlPositionShare> mlPositionShares) {
        BigDecimal wtSl = mlTradeEntrustOrder.getWtSl();
        if (wtSl == null || wtSl.compareTo(BigDecimal.ZERO) <= 0) {
            return;
        }
        for (MlPositionShare share : mlPositionShares) {
            if (wtSl.compareTo(BigDecimal.ZERO) == 0) {
                break;
            }
            BigDecimal kycw = share.getKyCw();
            if (kycw == null || kycw.compareTo(BigDecimal.ZERO) == 0) {
                share.setSdCw(BigDecimal.ZERO);
                continue;
            }
            if (kycw.compareTo(wtSl) >= 0) {
                share.setSdCw(wtSl.add(share.getSdCw()));
                share.setKyCw(kycw.subtract(wtSl));
                wtSl = BigDecimal.ZERO;
            } else {
                share.setSdCw(kycw);
                share.setKyCw(BigDecimal.ZERO);
                wtSl = wtSl.subtract(kycw);
            }
            share.setWtDh(mlTradeEntrustOrder.getWtDh());
            iMlPositionShareService.updateMlPositionShare(share);
        }
    }

    @Override
    public void mlTradeEntrustOrderCancel() {
        // 获取今天0点
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Date start = calendar.getTime();
// 获取明天0点
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        Date end = calendar.getTime();
// MyBatis-Plus 查询
        List<MlTradeEntrustOrder> mlTradeEntrustOrders = this.lambdaQuery()
                .ge(MlTradeEntrustOrder::getCreateTime, start)
                .lt(MlTradeEntrustOrder::getCreateTime, end).in(MlTradeEntrustOrder::getWtZt, "1", "2")
                .list();
        List<MlTradeEntrustOrder> needUpdateOrders = new ArrayList<>();
        for (MlTradeEntrustOrder mlTradeEntrustOrder : mlTradeEntrustOrders) {
            if (mlTradeEntrustOrder.getWtZt().compareTo(BigDecimal.ONE) == 0) {
                mlTradeEntrustOrder.setWtZt(new BigDecimal(5));
                String tdAcc = mlTradeEntrustOrder.getTdAcc();
                LambdaQueryWrapper<MlTradeAccount> mlTradeAccountLambdaQueryWrapper = new LambdaQueryWrapper<>();
                mlTradeAccountLambdaQueryWrapper.eq(MlTradeAccount::getTdAcc, tdAcc);
                MlTradeAccount mlTradeAccount = iMlTradeAccountService.getOne(mlTradeAccountLambdaQueryWrapper);
                BigDecimal sxf = this.countCommission(mlTradeAccount, mlTradeEntrustOrder.getTdAcc(), mlTradeEntrustOrder.getWtFx(), mlTradeEntrustOrder.getWtJg(), mlTradeEntrustOrder.getWtSl());
                BigDecimal aaLock = mlTradeEntrustOrder.getWtJg().multiply(mlTradeEntrustOrder.getWtSl()).add(sxf);
                mlTradeAccount.setAaLock(mlTradeAccount.getAaLock().subtract(aaLock));
                mlTradeAccount.setCash(mlTradeAccount.getCash().add(aaLock));
                mlTradeAccount.setKqZj(mlTradeAccount.getKqZj().add(aaLock));
                needUpdateOrders.add(mlTradeEntrustOrder);
            } else {
                mlTradeEntrustOrder.setWtZt(new BigDecimal(7));
                String tdAcc = mlTradeEntrustOrder.getTdAcc();
                LambdaQueryWrapper<MlTradeAccount> mlTradeAccountLambdaQueryWrapper = new LambdaQueryWrapper<>();
                mlTradeAccountLambdaQueryWrapper.eq(MlTradeAccount::getTdAcc, tdAcc);
                MlTradeAccount mlTradeAccount = iMlTradeAccountService.getOne(mlTradeAccountLambdaQueryWrapper);
                BigDecimal sxf = this.countCommission(mlTradeAccount, mlTradeEntrustOrder.getTdAcc(), mlTradeEntrustOrder.getWtFx(), mlTradeEntrustOrder.getWtJg(), mlTradeEntrustOrder.getSySl());
                //剩余数量花费
                BigDecimal syslAmount = mlTradeEntrustOrder.getWtJg().multiply(mlTradeEntrustOrder.getSySl()).add(sxf);
                mlTradeAccount.setAaLock(mlTradeAccount.getAaLock().subtract(syslAmount));
                mlTradeAccount.setCash(mlTradeAccount.getCash().add(syslAmount));
                mlTradeAccount.setKqZj(mlTradeAccount.getKqZj().add(syslAmount));
                needUpdateOrders.add(mlTradeEntrustOrder);
            }
        }
        if (!CollectionUtils.isEmpty(needUpdateOrders)){
            this.updateBatchById(mlTradeEntrustOrders,1000);
        }
    }

    public List<TodayDaealVo> buildToday(List<TodayDaealVo> todayDaeas) {
        Optional<TodayDaealVo> min = todayDaeas.stream().filter(d -> "B".equals(d.getBsFlag())).min(Comparator.comparingLong(d -> {
            try {
                LocalTime tickTime = LocalTime.parse(d.getFormatTime()); // 或 d.getTime()
                return Math.abs(Duration.between(LocalTime.now(), tickTime).toMillis());
            } catch (Exception e) {
                return Long.MAX_VALUE; // 时间格式错误的跳过
            }
        }));
        List<TodayDaealVo> resultList = min.map(Collections::singletonList).orElse(Collections.emptyList());
        return resultList;
    }


    BigDecimal countCommission(MlTradeAccount mlTradeAccount, String tdAcc, BigDecimal wtFx, BigDecimal cjSl, BigDecimal cjJg) {
        BigDecimal fee = BigDecimal.ZERO;
        if (wtFx.compareTo(BigDecimal.ZERO) == 0) {
            fee = cjJg.multiply(cjSl).multiply(mlTradeAccount.getBuyRate());
        }
        if (wtFx.compareTo(BigDecimal.ZERO) == 1) {
            fee = cjJg.multiply(cjSl).multiply(mlTradeAccount.getSellRate());
        }
        if (mlTradeAccount.getFFive().compareTo(BigDecimal.ZERO) == 0 && mlTradeAccount.getFFive().compareTo(new BigDecimal(5)) < 0) {
            fee = new BigDecimal(5);
        }
        return fee;
    }

    public String createDealDh() {
        Date date = new Date();
        DateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        String format = formatter.format(date);
        Random random = new Random();
        int randomNumber = random.nextInt(100000);
        String formattedNumber = String.format("%05d", randomNumber);
        return "CJ" + format + formattedNumber;
    }

    @Override
    public void entrustOrderCancel(String id) {
        MlTradeEntrustOrder mlTradeEntrustOrder = this.getById(id);
        mlTradeEntrustOrder.setWtZt(new BigDecimal(5));
        this.updateById(mlTradeEntrustOrder);
    }

    @Override
    public List<DeliveryOrderVo> getDeliveryOrderVo(String s_time, String e_time) {
        List<DeliveryOrderVo> deliveryOrderVos = new ArrayList<>();
//        LocalDate now = LocalDate.now();
//        LocalDate tomorrowDay = now.plusDays(1);
//        LocalDate sevenDaysAgo = now.minusDays(30);
        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String tdAcc = SecurityUtils.getLoginMember().getMlTradeAccount().getTdAcc();
        List<MlTradeEntrustOrder> list = this.lambdaQuery().eq(MlTradeEntrustOrder::getTdAcc, tdAcc).ge(MlTradeEntrustOrder::getCreateTime, s_time).le(MlTradeEntrustOrder::getCreateTime, e_time).list();
        for (MlTradeEntrustOrder mlTradeEntrustOrder : list) {
            BigDecimal cj_sl = BigDecimal.ZERO;
            BigDecimal cj_je = BigDecimal.ZERO;
            BigDecimal cj_sxf = BigDecimal.ZERO;
            DeliveryOrderVo deliveryOrderVo = new DeliveryOrderVo();
            MlSymbolsInfo mlSymbolsInfo = iMlSymbolsInfoService.lambdaQuery().eq(MlSymbolsInfo::getSecId, mlTradeEntrustOrder.getSymbol()).one();
            if (!ObjectUtils.isEmpty(mlSymbolsInfo)) {
                List<MlTradeDealOrder> dealOrderList = iMlTradeDealOrderService.lambdaQuery().eq(MlTradeDealOrder::getWtDh, mlTradeEntrustOrder.getWtDh()).list();
                if (!CollectionUtils.isEmpty(dealOrderList)) {
                    for (MlTradeDealOrder mlTradeDealOrder : dealOrderList) {
                        cj_sl = cj_sl.add(mlTradeDealOrder.getCjSl());
                        cj_je = cj_je.add(mlTradeDealOrder.getCjJg().multiply(mlTradeDealOrder.getCjSl()));
                        cj_sxf = cj_sxf.add(mlTradeDealOrder.getCjSxf());
                    }
                    deliveryOrderVo.setDTime(formatter.format(dealOrderList.get(0).getCreateTime()));
                    deliveryOrderVo.setCjJg(dealOrderList.get(0).getCjJg());
                }
                deliveryOrderVo.setSecName(mlSymbolsInfo.getSecName());
                deliveryOrderVo.setSecId(mlSymbolsInfo.getSecId());
                deliveryOrderVo.setCCash(mlTradeEntrustOrder.getWtFx().compareTo(BigDecimal.ZERO) == 0 ? mlTradeEntrustOrder.getWtSl().multiply(mlTradeEntrustOrder.getWtJg()).multiply(new BigDecimal(-1)) : mlTradeEntrustOrder.getWtSl().multiply(mlTradeEntrustOrder.getWtJg()));
                deliveryOrderVo.setCDate(formatter.format(mlTradeEntrustOrder.getCreateTime()));
                deliveryOrderVo.setWtFx(mlTradeEntrustOrder.getWtFx().compareTo(BigDecimal.ZERO) == 0 ? "买入" : "卖出");
                deliveryOrderVo.setCjSl(cj_sl);
                deliveryOrderVo.setCjJe(cj_je);
                deliveryOrderVo.setCjSxf(cj_sxf);
                deliveryOrderVo.setCjYhs(BigDecimal.ZERO);
                deliveryOrderVo.setCjQtf(BigDecimal.ZERO);
                deliveryOrderVos.add(deliveryOrderVo);
            }
        }
        return deliveryOrderVos;
    }


    /**
     * 交易方法定时任务
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void tradingOrder() throws Exception {
        LocalTime now = LocalTime.now();
        LocalTime startTime = LocalTime.of(9, 30);
        LocalTime endTime = LocalTime.of(15, 0);
//        if (now.isAfter(startTime) && now.isBefore(endTime)) {
        List<MlTradeEntrustOrder> mlTradeEntrustOrders = this.lambdaQuery().in(MlTradeEntrustOrder::getWtZt, "0", "4").list();
        for (MlTradeEntrustOrder mlTradeEntrustOrder : mlTradeEntrustOrders) {
            if (mlTradeEntrustOrder.getWtZt().compareTo(BigDecimal.ZERO) == 0) {
                if (this.isTradeDay() || this.isTradingStatus()) {
                    mlTradeEntrustOrder.setWtZt(BigDecimal.ONE);
                    this.updateById(mlTradeEntrustOrder);
                }
            } else if (mlTradeEntrustOrder.getWtZt().compareTo(new BigDecimal(4)) == 0) {
                if (this.isTradeDay()) {
                    continue;
                }
                this.entrustOrderCancel(String.valueOf(mlTradeEntrustOrder.getId()));
            }
        }
        List<MlTradeEntrustOrder> mlTradeEntrustOrderList = this.lambdaQuery().in(MlTradeEntrustOrder::getWtZt, "1", "2").eq(MlTradeEntrustOrder::getChZt, BigDecimal.ONE).list();
//        List<MlTradeEntrustOrder> mlTradeEntrustOrderList = this.lambdaQuery().eq(MlTradeEntrustOrder::getWtDh, "WT2025072470135")
//                .list();
        for (MlTradeEntrustOrder mlTradeEntrustOrder : mlTradeEntrustOrderList) {
            String tdAcc = mlTradeEntrustOrder.getTdAcc();
            LambdaQueryWrapper<MlTradeAccount> mlTradeAccountLambdaQueryWrapper = new LambdaQueryWrapper<>();
            mlTradeAccountLambdaQueryWrapper.eq(MlTradeAccount::getTdAcc, tdAcc);
            MlTradeAccount mlTradeAccount = iMlTradeAccountService.getOne(mlTradeAccountLambdaQueryWrapper);
            if (mlTradeEntrustOrder.getWtZt().compareTo(BigDecimal.ONE) == 0 || mlTradeEntrustOrder.getWtZt().compareTo(new BigDecimal(2)) == 0) {
                BigDecimal cash = mlTradeAccount.getCash();
                int randomNumber = ThreadLocalRandom.current().nextInt(180, 360);
                mlTradeEntrustOrder.setChSjc((long) randomNumber);
                //买入
                List<TodayDaealVo> todayDaeas = this.getTodayDaea(mlTradeEntrustOrder.getSymbol(), mlTradeEntrustOrder.getSecName());
                if (mlTradeEntrustOrder.getWtFx().compareTo(BigDecimal.ZERO) == 0) {
                    List<TodayDaealVo> resultList = buildToday(todayDaeas);
                    for (TodayDaealVo todayDaealVo : resultList) {
                        if (todayDaealVo.getPrice().compareTo(mlTradeEntrustOrder.getWtJg()) == 0) {
                            BigDecimal wtJg = getBigDecimal(mlTradeEntrustOrder, todayDaealVo);
                            createMlpositionShare(mlTradeEntrustOrder, mlTradeAccount.getTdAcc());
                            this.createDealOrderJob(mlTradeEntrustOrder, wtJg, cash, wtJg, mlTradeAccount);
                            this.updateById(mlTradeEntrustOrder);
                        }
                    }
                } else if (mlTradeEntrustOrder.getWtFx().compareTo(BigDecimal.ONE) == 0) {
                    List<TodayDaealVo> resultList = createStoday(todayDaeas);
                    for (TodayDaealVo todayDaealVo : resultList) {
                        if (todayDaealVo.getPrice().compareTo(mlTradeEntrustOrder.getWtJg()) == 0) {
                            BigDecimal wtJg = getBigDecimal(mlTradeEntrustOrder, todayDaealVo);
                            mlTradeAccount.setDjCash(mlTradeAccount.getDjCash().add(wtJg.multiply(mlTradeEntrustOrder.getWtSl())));
                            LocalDate date = LocalDateTime.now().toLocalDate();
                            LambdaQueryWrapper<MlPositionShare> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                            lambdaQueryWrapper.eq(MlPositionShare::getTdAcc, tdAcc).eq(MlPositionShare::getSymbol, mlTradeEntrustOrder.getSymbol()).lt(MlPositionShare::getCreateTime, date).orderByAsc(MlPositionShare::getCreateTime);
                            List<MlPositionShare> mlPositionShares = iMlPositionShareService.list(lambdaQueryWrapper);
                            mlTradeDealOrderServiceimpl.createDealOrder(mlTradeEntrustOrder, mlTradeEntrustOrder.getWtJg(), String.valueOf(mlTradeEntrustOrder.getWtSl()), System.currentTimeMillis(), mlPositionShares, "0");
                            this.updateById(mlTradeEntrustOrder);
                        }
                    }
                }
            }
        }

    }

    @Transactional
    void createDealOrderJob(MlTradeEntrustOrder mlTradeEntrustOrder, BigDecimal bid_p, BigDecimal cash, BigDecimal wtJg1, MlTradeAccount mlTradeAccount) {
        MlTradeDealOrder mlTradeDealOrder = new MlTradeDealOrder();
        mlTradeDealOrder.setCreateTime(new Date());
        mlTradeDealOrder.setWtDh(mlTradeEntrustOrder.getWtDh());
        mlTradeDealOrder.setCjDh(this.createDealDh());
        mlTradeDealOrder.setSymbol(mlTradeEntrustOrder.getSymbol());
        mlTradeDealOrder.setTdAcc(mlTradeEntrustOrder.getTdAcc());
        mlTradeDealOrder.setCjJg(mlTradeEntrustOrder.getWtJg());
        mlTradeDealOrder.setCjFx(mlTradeEntrustOrder.getWtFx());
        mlTradeDealOrder.setCjJg(bid_p);
        mlTradeDealOrder.setCjSl(mlTradeEntrustOrder.getCjSl());
        mlTradeDealOrder.setCjSj(System.currentTimeMillis());
        mlTradeDealOrder.setSecName(mlTradeEntrustOrder.getSecName());
        BigDecimal sxf = this.countCommission(mlTradeAccount, mlTradeEntrustOrder.getTdAcc(), mlTradeEntrustOrder.getWtFx(), mlTradeDealOrder.getCjSl(), mlTradeDealOrder.getCjJg());
        mlTradeDealOrder.setCjSxf(sxf);
        List<MlTradeDealOrder> resultList = iMlTradingGroupService.splitRecursively(mlTradeDealOrder);
        for (MlTradeDealOrder tradeDealOrder : resultList) {
            iMlTradeDealOrderService.save(tradeDealOrder);
        }
        iMlBtsPointService.createBtsToTrading(mlTradeEntrustOrder.getTdAcc(), mlTradeEntrustOrder.getSymbol(), 0);
        /**
         * 定时任务成交时将锁定金额扣除
         */
        BigDecimal zhf = mlTradeEntrustOrder.getWtJg().multiply(mlTradeEntrustOrder.getCjSl()).add(sxf);
        mlTradeAccount.setAaLock(mlTradeAccount.getAaLock().subtract(zhf));
        iMlTradeAccountService.updateById(mlTradeAccount);
    }

    private void createDealOrder(MlTradeEntrustOrder mlTradeEntrustOrder, BigDecimal bid_p, BigDecimal cash, BigDecimal wtJg, MlTradeAccount mlTradeAccount) throws Exception {
        MlTradeDealOrder mlTradeDealOrder = new MlTradeDealOrder();
        mlTradeDealOrder.setCreateTime(new Date());
        mlTradeDealOrder.setWtDh(mlTradeEntrustOrder.getWtDh());
        mlTradeDealOrder.setCjDh(this.createDealDh());
        mlTradeDealOrder.setSymbol(mlTradeEntrustOrder.getSymbol());
        mlTradeDealOrder.setTdAcc(mlTradeEntrustOrder.getTdAcc());
        mlTradeDealOrder.setCjJg(mlTradeEntrustOrder.getWtJg());
        mlTradeDealOrder.setCjFx(mlTradeEntrustOrder.getWtFx());
        mlTradeDealOrder.setCjJg(bid_p);
        mlTradeDealOrder.setCjSl(mlTradeEntrustOrder.getCjSl());
        mlTradeDealOrder.setCjSj(System.currentTimeMillis());
        mlTradeDealOrder.setSecName(mlTradeEntrustOrder.getSecName());
        BigDecimal sxf = this.countCommission(mlTradeAccount, mlTradeEntrustOrder.getTdAcc(), mlTradeEntrustOrder.getWtFx(), mlTradeDealOrder.getCjSl(), mlTradeDealOrder.getCjJg());
        mlTradeDealOrder.setCjSxf(sxf);
        List<MlTradeDealOrder> resultList = iMlTradingGroupService.splitRecursively(mlTradeDealOrder);
        for (MlTradeDealOrder tradeDealOrder : resultList) {
            iMlTradeDealOrderService.save(tradeDealOrder);
            iMlAssetFlowService.creatObject(mlTradeEntrustOrder.getTdAcc(), 2, mlTradeDealOrder.getCjJg().multiply(mlTradeDealOrder.getCjSl()).multiply(new BigDecimal(-1)));
        }
        iMlBtsPointService.createBtsToTrading(mlTradeEntrustOrder.getTdAcc(), mlTradeEntrustOrder.getSymbol(), 0);
        iMlTodayProfitService.changeProfit(mlTradeEntrustOrder.getTdAcc(), sxf.multiply(new BigDecimal(-1)));
        iMlAssetFlowService.creatObject(mlTradeEntrustOrder.getTdAcc(), 4, sxf.multiply(new BigDecimal(-1)));
        /**
         * 买入扣款
         */
        this.mlTradeAccountSetData(mlTradeAccount, wtJg, mlTradeEntrustOrder.getCjSl(), sxf);
        iMlTradeAccountService.updateById(mlTradeAccount);
    }


    void createMlpositionShare(MlTradeEntrustOrder mlTradeEntrustOrder, String tdAcc) {
        MlPositionShare mlPositionShare = new MlPositionShare();
        mlPositionShare.setCreateTime(new Date());
        mlPositionShare.setSymbol(mlTradeEntrustOrder.getSymbol());
        mlPositionShare.setTdAcc(mlTradeEntrustOrder.getTdAcc());
        mlPositionShare.setKyCw(mlTradeEntrustOrder.getCjSl());
        mlPositionShare.setSdCw(BigDecimal.ZERO);
        mlPositionShare.setCbJj(mlTradeEntrustOrder.getWtJg());
//        mlTradeEntrustOrder.setSySl(mlPositionShare.getKyCw());
        String ccdh = this.createrDH("CC");
        mlPositionShare.setCcDh(ccdh);
        mlPositionShare.setWtDh(mlTradeEntrustOrder.getWtDh());
        mlTradeEntrustOrder.setCcDh(ccdh);
        iMlPositionShareService.save(mlPositionShare);
    }


    @Override
    public AjaxResult entrustOrderInsert(MlTradeEntrustOrder mlTradeEntrustOrder) throws Exception {
        String tdAcc = mlTradeEntrustOrder.getTdAcc();
        LambdaQueryWrapper<MlTradeAccount> mlTradeAccountLambdaQueryWrapper = new LambdaQueryWrapper<>();
        mlTradeAccountLambdaQueryWrapper.eq(MlTradeAccount::getTdAcc, tdAcc);
        MlTradeAccount mlTradeAccount = iMlTradeAccountService.getOne(mlTradeAccountLambdaQueryWrapper);
        if (mlTradeEntrustOrder.getWtZt().compareTo(BigDecimal.ONE) == 0) {
            BigDecimal bid_p = mlTradeEntrustOrder.getWtJg();
            BigDecimal wtJg = mlTradeEntrustOrder.getWtJg();
            BigDecimal cash = mlTradeAccount.getCash();
            String wtSl = String.valueOf(mlTradeEntrustOrder.getWtSl());
            int randomNumber = ThreadLocalRandom.current().nextInt(180, 360);
            mlTradeEntrustOrder.setChSjc((long) randomNumber);
            //买入
            if (mlTradeEntrustOrder.getWtFx().compareTo(BigDecimal.ZERO) == 0) {
                createMlpositionShare(mlTradeEntrustOrder, mlTradeAccount.getTdAcc());
                this.createDealOrder(mlTradeEntrustOrder, bid_p, cash, wtJg, mlTradeAccount);
                mlTradeEntrustOrder.setWtZt(new BigDecimal(3));
                this.updateById(mlTradeEntrustOrder);
            } else if (mlTradeEntrustOrder.getWtFx().compareTo(BigDecimal.ONE) == 0) {
                mlTradeAccount.setDjCash(mlTradeAccount.getDjCash().add(wtJg.multiply(mlTradeEntrustOrder.getWtSl())));
                mlTradeEntrustOrder.setWtZt(new BigDecimal(3));
                LocalDate date = LocalDateTime.now().toLocalDate();
                LambdaQueryWrapper<MlPositionShare> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(MlPositionShare::getTdAcc, tdAcc).eq(MlPositionShare::getSymbol, mlTradeEntrustOrder.getSymbol()).lt(MlPositionShare::getCreateTime, date).orderByAsc(MlPositionShare::getCreateTime);
                List<MlPositionShare> mlPositionShares = iMlPositionShareService.list(lambdaQueryWrapper);
                iMlTradeDealOrderService.createDealOrder(mlTradeEntrustOrder, wtJg, wtSl, System.currentTimeMillis(), mlPositionShares, "0");
            }
        }
        return AjaxResult.success();
    }


    @Override
    public void mlTradeAccountSetData(MlTradeAccount mlTradeAccount, BigDecimal cjJg, BigDecimal cjSl, BigDecimal sxf) throws Exception {
        List<MlTradeAccountFinancing> mlTradeAccountFinancings = iMlTradeAccountFinancingService.lambdaQuery().eq(MlTradeAccountFinancing::getTdAcc, mlTradeAccount.getTdAcc()).orderByAsc(MlTradeAccountFinancing::getCreateTime).list();
        BigDecimal zhf = cjJg.multiply(cjSl).add(sxf);
        BigDecimal zYyEd = mlTradeAccountFinancings.stream().map(MlTradeAccountFinancing::getYyEd).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal zEd = mlTradeAccountFinancings.stream().map(MlTradeAccountFinancing::getAlimit).reduce(BigDecimal.ZERO, BigDecimal::add);
        if (!CollectionUtils.isEmpty(mlTradeAccountFinancings)) {
            BigDecimal ratio = this.percentToDouble(mlTradeAccount.getFinancingRatio());
            BigDecimal zRatio = ratio.add(BigDecimal.ONE);
            //要扣的金额
            BigDecimal financingNum = zhf.divide(zRatio, 2, RoundingMode.HALF_UP).multiply(ratio);
            mlTradeAccount.setCash(mlTradeAccount.getCash().subtract(zhf.subtract(financingNum)));
            //总剩余额度
            BigDecimal zSyEd = zEd.subtract(zYyEd);
            if (zSyEd.subtract(zYyEd).compareTo(financingNum) < 0) {
                mlTradeAccount.setCash(mlTradeAccount.getCash().subtract(zhf));
                return;
            }
            for (MlTradeAccountFinancing financing : mlTradeAccountFinancings) {
                if (financingNum.compareTo(BigDecimal.ZERO) == 0) break;
                //剩余额度
                BigDecimal syed = financing.getAlimit().subtract(financing.getYyEd());
                if (syed.compareTo(financingNum) >= 0) {
                    // 当前融资额度足够扣
                    financing.setYyEd(financing.getYyEd().add(financingNum));
                    financingNum = BigDecimal.ZERO;
                } else {
                    // 不够扣光，继续下一个
                    financing.setYyEd(financing.getAlimit());
                    financingNum = financingNum.subtract(syed);
                }
            }
            iMlTradeAccountFinancingService.updateBatchById(mlTradeAccountFinancings);
        } else {
            if (mlTradeAccount.getCash().compareTo(zhf) >= 0 && mlTradeAccount.getKqZj().compareTo(zhf) >= 0) {
                mlTradeAccount.setCash(mlTradeAccount.getCash().subtract(zhf));
                mlTradeAccount.setKqZj(mlTradeAccount.getKqZj().subtract(zhf));
            } else {
                mlTradeAccount.setDjCash(mlTradeAccount.getDjCash().subtract(zhf));
            }
        }
    }

    @Override
    public void setSellSymbolData(MlTradeAccount mlTradeAccount, BigDecimal cjJg, String cjSl, BigDecimal sxf) {
        BigDecimal zsr = cjJg.multiply(new BigDecimal(cjSl)).subtract(sxf);
        List<MlTradeAccountFinancing> mlTradeAccountFinancings = iMlTradeAccountFinancingService.lambdaQuery().eq(MlTradeAccountFinancing::getTdAcc, mlTradeAccount.getTdAcc()).orderByAsc(MlTradeAccountFinancing::getCreateTime).list();
        if (!mlTradeAccountFinancings.isEmpty()) {
            for (MlTradeAccountFinancing financing : mlTradeAccountFinancings) {
                if (zsr.compareTo(BigDecimal.ZERO) == 0) break;
                BigDecimal used = financing.getYyEd();
                if (used.compareTo(zsr) <= 0) {
                    // 这条融资能还清
                    zsr = zsr.subtract(used);
                    financing.setYyEd(BigDecimal.ZERO);
                } else {
                    // 只能还部分
                    financing.setYyEd(used.subtract(zsr));
                    zsr = BigDecimal.ZERO;
                }
            }
            iMlTradeAccountFinancingService.updateBatchById(mlTradeAccountFinancings);
        }
        mlTradeAccount.setDjCash(mlTradeAccount.getDjCash().add(zsr));
    }

    @Override
    public void createmlTradeEntrustOrder(MlTradeEntrustOrder mlTradeEntrustOrder) {
        mlTradeEntrustOrder.setWtZt(BigDecimal.valueOf(1));
        mlTradeEntrustOrder.setCreateTime(new Date());
        mlTradeEntrustOrder.setChZt(BigDecimal.ZERO);
        mlTradeEntrustOrder.setPriceCount(BigDecimal.ZERO);
        mlTradeEntrustOrder.setCjSl(BigDecimal.ZERO);
        this.insertMlTradeEntrustOrder(mlTradeEntrustOrder);
    }

    @Autowired
    private RedisCache redisCache;

    @Override
    public void priceCountaddJob() throws Exception {
        // 1. 获取redis里的priceCount
        Object cacheObject = redisCache.getCacheObject("sys_config:sys.MlTradeEntrustOrder.priceCount");
        String count = String.valueOf(cacheObject);
        BigDecimal bigDecimal = new BigDecimal(count);

        // 2. 查询所有待处理委托订单
        LambdaQueryWrapper<MlTradeEntrustOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MlTradeEntrustOrder::getChZt, BigDecimal.ZERO)
                .in(MlTradeEntrustOrder::getWtZt, 1, 2)
                .lt(MlTradeEntrustOrder::getPriceCount, bigDecimal);
        List<MlTradeEntrustOrder> orders = this.list(wrapper);
        if (orders.isEmpty()) return;

        // 3. 批量查账户
        Set<String> tdAccSet = orders.stream().map(MlTradeEntrustOrder::getTdAcc).collect(Collectors.toSet());
        Map<String, MlTradeAccount> accountMap = iMlTradeAccountService.getAccountMapByTdAccs(tdAccSet);

        // 4. 批量查持仓
        // 可根据需要补充参数组合Key
        Map<String, List<MlPositionShare>> positionMap = iMlPositionShareService.getPositionMapByTdAccAndSymbol(orders);

        // 5. 缓存行情数据
        Map<String, List<TodayDaealVo>> todayDaealMap = new HashMap<>();

        List<MlTradeEntrustOrder> needUpdateOrders = new ArrayList<>();

        for (MlTradeEntrustOrder order : orders) {
            String symbol = order.getSymbol();
            String secName = order.getSecName();
            String tdAcc = order.getTdAcc();
            String key = symbol + "_" + secName;

            // 缓存行情
            List<TodayDaealVo> todayDeals = todayDaealMap.computeIfAbsent(key, k -> {
                try {
                    return getTodayDaea(symbol, secName);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            });
            Optional<TodayDaealVo> minOpt = todayDeals.stream().min(Comparator.comparingLong(d -> {
                try {
                    LocalTime tickTime = LocalTime.parse(d.getFormatTime());
                    return Math.abs(Duration.between(LocalTime.now(), tickTime).toMillis());
                } catch (Exception e) {
                    return Long.MAX_VALUE;
                }
            }));
            List<TodayDaealVo> resultList = minOpt.map(Collections::singletonList).orElse(Collections.emptyList());

            // 获取账户、持仓
            MlTradeAccount account = accountMap.get(tdAcc);
            List<MlPositionShare> positions = positionMap.getOrDefault(tdAcc + "_" + symbol, Collections.emptyList());

            // 买
            if (order.getWtFx().compareTo(BigDecimal.ZERO) == 0) {
                for (TodayDaealVo todayDaealVo : resultList) {
                    if (order.getWtJg().compareTo(todayDaealVo.getPrice()) > 0) {
                        BigDecimal wtJg = getBigDecimal(order, todayDaealVo);
                        BigDecimal cash = account.getCash();
                        int randomNumber = ThreadLocalRandom.current().nextInt(180, 360);
                        order.setChSjc((long) randomNumber);
                        createMlpositionShare(order, account.getTdAcc());
                        createDealOrderJob(order, wtJg, cash, wtJg, account); // 生成成交单
                        order.setChZt(BigDecimal.ONE);
                    } else if (order.getWtJg().compareTo(todayDaealVo.getPrice()) == 0) {
                        order.setPriceCount(order.getPriceCount().add(BigDecimal.ONE));
                        if (order.getPriceCount().compareTo(bigDecimal) == 0) {
                            order.setChZt(BigDecimal.ONE);
                        }
                    }
                }
            } else { // 卖
                for (TodayDaealVo todayDaealVo : resultList) {
                    if (order.getWtJg().compareTo(todayDaealVo.getPrice()) < 0) {
                        BigDecimal wtJg = getBigDecimal(order, todayDaealVo);
                        int randomNumber = ThreadLocalRandom.current().nextInt(180, 360);
                        order.setChSjc((long) randomNumber);
                        account.setDjCash(account.getDjCash().add(wtJg.multiply(order.getWtSl())));
                        order.setWtZt(new BigDecimal(3));
                        mlTradeDealOrderServiceimpl.createDealOrder(order, order.getWtJg(), String.valueOf(order.getWtSl()), System.currentTimeMillis(), positions, "0");
                        order.setChZt(BigDecimal.ONE);
                    } else if (order.getWtJg().compareTo(todayDaealVo.getPrice()) == 0) {
                        order.setPriceCount(order.getPriceCount().add(BigDecimal.ONE));
                        if (order.getPriceCount().compareTo(bigDecimal) == 0) {
                            order.setChZt(BigDecimal.ONE);
                        }
                    }
                }
            }
            needUpdateOrders.add(order);
        }

        // 批量更新
        if (!needUpdateOrders.isEmpty()) {
            this.updateBatchById(needUpdateOrders, 1000);
        }
    }

    @Override
    public void createmlTradeEntrustAddOrsubtract(MlTradeAccount mlTradeAccount, MlTradeEntrustOrder mlTradeEntrustOrder) {
        BigDecimal sxf = this.countCommission(mlTradeAccount, mlTradeEntrustOrder.getTdAcc(), mlTradeEntrustOrder.getWtFx(), mlTradeEntrustOrder.getWtJg(), mlTradeEntrustOrder.getWtSl());
        BigDecimal aaLock = mlTradeEntrustOrder.getWtJg().multiply(mlTradeEntrustOrder.getWtSl()).add(sxf);
        if (mlTradeAccount.getCash().compareTo(aaLock) >= 0 && mlTradeAccount.getKqZj().compareTo(aaLock) >= 0) {
            mlTradeAccount.setCash(mlTradeAccount.getCash().subtract(aaLock));
            mlTradeAccount.setKqZj(mlTradeAccount.getKqZj().subtract(aaLock));
        } else {
            mlTradeAccount.setDjCash(mlTradeAccount.getDjCash().subtract(aaLock));
        }
        mlTradeAccount.setAaLock(mlTradeAccount.getAaLock().add(aaLock));
        iMlTodayProfitService.changeProfit(mlTradeEntrustOrder.getTdAcc(), sxf.multiply(new BigDecimal(-1)));
        iMlAssetFlowService.creatObject(mlTradeEntrustOrder.getTdAcc(), 2, mlTradeEntrustOrder.getWtJg().multiply(mlTradeEntrustOrder.getWtSl()).multiply(new BigDecimal(-1)));
        iMlAssetFlowService.creatObject(mlTradeEntrustOrder.getTdAcc(), 4, sxf.multiply(new BigDecimal(-1)));
        iMlTradeAccountService.updateById(mlTradeAccount);
    }

    @Override
    public void checkDate(MlTradeEntrustOrder mlTradeEntrustOrder) throws Exception {
        MlPositionShare one = iMlPositionShareService.lambdaQuery().eq(MlPositionShare::getId, mlTradeEntrustOrder.getId()).one();
        SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
        Date createTime = one.getCreateTime();
        String format = fmt.format(createTime);
        boolean isNowDate = format.equals(fmt.format(new Date()));
        if (isNowDate) {
            throw new Exception("当天买入的股票不允许卖出交易!");
        }
    }

    @Override
    public String createrDH(String wt) {
        Date date = new Date();
        DateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        String format = formatter.format(date);
        Random random = new Random();
        int randomNumber = random.nextInt(100000);
        String formattedNumber = String.format("%05d", randomNumber);
        String wtDh = wt + format + formattedNumber;
        return wtDh;
    }

    @Override
    public List<TodayDaealVo> getTodayDaea(String symbol, String secName) throws Exception {
        List<TodayDaealVo> recentTicks;
        String symbol1 = "sh" + symbol;
        recentTicks = mlKLineMasterService.fetchLatestTicks(symbol1, 2);
        if (CollectionUtils.isEmpty(recentTicks)) {
            String symbol2 = "sz" + symbol;
            recentTicks = mlKLineMasterService.fetchLatestTicks(symbol2, 2);
        } else if (CollectionUtils.isEmpty(recentTicks)) {
            String symbol3 = "bj" + symbol;
            recentTicks = mlKLineMasterService.fetchLatestTicks(symbol3, 2);
        }
        if (CollectionUtils.isEmpty(recentTicks)) {
            throw new Exception("未获取到大盘实时价格数据！");
        }
        return recentTicks;
    }

    @Override
    public BigDecimal getBigDecimal(MlTradeEntrustOrder mlTradeEntrustOrder, TodayDaealVo todayDaealVo) {
        BigDecimal wtJg;
        wtJg = todayDaealVo.getPrice();
        mlTradeEntrustOrder.setWtJg(todayDaealVo.getPrice());
        if (mlTradeEntrustOrder.getWtSl().compareTo(todayDaealVo.getVolume()) > 0 && (mlTradeEntrustOrder.getCjSl() == null ? BigDecimal.ZERO : mlTradeEntrustOrder.getCjSl()).compareTo(mlTradeEntrustOrder.getWtSl()) < 0) {
            mlTradeEntrustOrder.setCjSl((mlTradeEntrustOrder.getCjSl() == null ? BigDecimal.ZERO : mlTradeEntrustOrder.getCjSl()).add(todayDaealVo.getVolume()));
            mlTradeEntrustOrder.setSySl(mlTradeEntrustOrder.getWtSl().subtract(mlTradeEntrustOrder.getCjSl()));
            mlTradeEntrustOrder.setWtZt(new BigDecimal(2));
            mlTradeEntrustOrder.setChZt(BigDecimal.ZERO);
        } else {
            mlTradeEntrustOrder.setCjSl(mlTradeEntrustOrder.getWtSl());
            mlTradeEntrustOrder.setSySl(BigDecimal.ZERO);
            mlTradeEntrustOrder.setWtZt(new BigDecimal(3));
            mlTradeEntrustOrder.setChZt(BigDecimal.ONE);
        }
        return wtJg;
    }

    private BigDecimal percentToDouble(String financingRatio) {
        if (financingRatio == null || !financingRatio.endsWith("%")) {
            throw new IllegalArgumentException("输入必须以%结尾");
        }
        String numStr = financingRatio.substring(0, financingRatio.length() - 1);
        BigDecimal num = new BigDecimal(numStr);

        return num.divide(new BigDecimal(100));
    }

    private boolean isTradingStatus() {
        LocalTime date1 = LocalTime.of(9, 30, 0);
        LocalTime date2 = LocalTime.of(15, 0, 0);
        LocalDateTime now = LocalDateTime.now();
        LocalTime time = now.toLocalTime();
        String timeStr = time.format(DateTimeFormatter.ofPattern("HH:mm"));
        if (LocalTime.parse(timeStr).isAfter((date1)) && LocalTime.parse(timeStr).isBefore(date2)) {
            return true;
        } else {
            return false;
        }
    }

    // 设定股票交易日的基本规则
    private static final Set<DayOfWeek> weekdays = Set.of(DayOfWeek.MONDAY, DayOfWeek.TUESDAY, DayOfWeek.WEDNESDAY, DayOfWeek.THURSDAY, DayOfWeek.FRIDAY);
    private static final Set<Integer> holidays = new HashSet<>();

    static {
        // 添加股票交易所假日
        holidays.add(1225); // 平安夜
        holidays.add(1226); // 圣诞节
        // ... 添加其他股票交易所假日
    }

    private boolean isTradeDay() {
        LocalDate today = LocalDate.now();
        return isStockExchangeDay(today);
    }


    private boolean isStockExchangeDay(LocalDate date) {
        DayOfWeek dayOfWeek = date.getDayOfWeek();
        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        List<String> HolidayTimes = iMlHolidayService.list().stream().map(e -> formatter.format(e.getHolidayTime())).collect(Collectors.toList());
        // 周末不是交易日
        if (!weekdays.contains(dayOfWeek)) {
            return false;
        }
        // 假日不是交易日
        if (HolidayTimes.contains(date)) {
            return false;
        }
        return true;
    }


}
